var fs = require("fs");
var path = require("path");
var config = require('../../config.json');
var local_repos = config.local_repo_addr;
var LocalRepoProxy = require('../../proxy/local_repo.js');
var logger = require('log4js').getLogger();
var messageBroker = require('../../messageBroker.js');
var uuid = require('uuid');
var zip = require('../../common/zip.js');
var EventProxy = require('eventproxy');
var decompress = require('decompress');
var decompressUnzip = require('decompress-unzip');
var taskProxy = require('../../proxy/task.js');
var removeDir = require('../../common/removeDir.js');
/**
 * 下载商品
 * POST请求
 * @param：{fileName:"",version:"",other_info:"",type:""}
 */

exports.download = function (req, res, next) {
    //var task_id = uuid.v1();
    //task_des:{type:string},
    //task_type:{type:string},
    //task_name:{type:string},
    //creator:{type:string},
    //state:{type:string},
    var task = {
        task_type: "download",
        task_name: req.body.fileName + "下载",
        creator: req.session.user.shortid,
        state: "executing"
    };
    taskProxy.create_task(task, function (err, data) {
        if (err) {
            logger.info("download task create failed:" + task.user.loginname + "download" + req.body.fileName + "error");
            res.format_json(null, 500, "下载任务发起失败");
        } else {
            var task_id = data._id;
            var task = data;
            res.format_json({task_id: task_id}, 0);
            downloadGoods(req.body.version, req.body.fileName, req.body.type, function (err, data) {
                if (err) {
                    taskProxy.update_task_state(task,"failed",function(err){
                        messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "下载文件失败"});
                        logger.error("下载文件失败：" + err)
                    });
                } else {
                    LocalRepoProxy.addLocalRepo({
                        fileName: req.body.fileName,
                        version: req.body.version,
                        other_info: req.body.other_info
                    }, function (err, data) {
                        if (err) {
                            taskProxy.update_task_state(task,"failed",function(err){
                                messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "下载文件失败"});
                                logger.error("下载文件失败：" + err)
                            });
                        } else {
                            taskProxy.update_task_state(task,"success",function(err){
                                messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: null});
                                messageBroker.emit('dependency_download', {body: req.body, err: null});
                                logger.info("下载文件成功")
                            });
                        }
                    });
                }

            });
        }
    });

};

/**
 * 更新本地仓库文件和数据库版本信息
 * PUT请求
 * @param：{fileName:"",version:""}
 */

exports.update = function (req, res, next) {
    var task_id = uuid.v1();
    res.format_json({task_id: task_id}, 200);
    setTimeout(function () {  //不靠谱
        var fileName = req.body.fileName;
        var version = req.body.version;
        var type = req.body.type;
        LocalRepoProxy.getLocalRepoByFileName(fileName,
            function (err, data) {
                if (err) {
                    messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "依赖更新失败"});
                    logger.error("从本地仓库获取依赖信息失败：" + err);
                } else {
                    if (data) {
                        if (data.version == version) {  //本地仓库中有目标版本
                            LocalRepoProxy.updateLocalRepo(
                                fileName, version, function (err, data) {
                                    if (err) {
                                        messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "依赖更新失败"});
                                        logger.error("依赖更新失败：" + err);
                                    } else {
                                        messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: null});
                                        messageBroker.emit('dependency_update', {body: req.body, err: null});
                                        logger.info("依赖更新成功");
                                    }
                                });
                        } else {                                 //本地仓库中没有 先下载 再更新
                            updateGoods(fileName, version,type, function (err) {
                                if (err) {
                                    messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "依赖更新失败"});
                                    logger.error("依赖更新失败：" + err);
                                } else {
                                    messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: null});
                                    messageBroker.emit('dependency_update', {body: req.body, err: null});
                                    logger.info("依赖更新成功");
                                }
                            });
                        }
                    } else {
                        messageBroker.emit(task_id, {task_id: task_id, body: req.body, err: "依赖更新失败"});
                        logger.error("从本地仓库获取依赖信息失败：" + err);
                    }
                }
            }
        );
    }, 200);
};

/**
 * 更新本地仓库文件和数据库版本信息
 * @param：{fileName:"",version:""}
 */
function updateGoods(fileName, version,type, cb) {
    downloadGoods(version, fileName,type, function (err, data) {
        if (err) {
            cb(err);
        } else {
            LocalRepoProxy.updateLocalRepo(
                fileName, version
                , function (err, data) {
                    if (err) {
                        cb(err);
                    } else {
                        cb();
                    }
                });
        }

    });


}


/**
 *下载商品
 */
function downloadGoods(version, fileName, type, callback) {
    var request = require('request');
    request(config.store.store_private + '/store/query_download?name=' + fileName + '_' + version, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var body = JSON.parse(body);
            if (body && body.data && body.data.url) {
                logger.info("get down_load_uri:" + body.data.url);
                request.get(body.data.url).on('response', function (response) {
                    if (response.statusCode != 200) {
                        exe_callback("未知的错误，下载失败", null, callback);
                    } else {
                        logger.info("downloading...");
                        var dependency_dir = path.join(local_repos, fileName + "_" + version);
                        var zip_path = path.join(local_repos, fileName + "_" + version + ".zip");
                        var writeStream = fs.createWriteStream(zip_path);
                        response.pipe(writeStream);
                        writeStream.on('close', function () {
                            //依赖下载后 先解压到fileName目录下，如果是mk 需要读取目录后再次解压
                            //依赖下载为zip文件后，根据不同类型解压
                            var epc = new EventProxy();
                            epc.after("file_existed", 1, function () {
                                decompress(zip_path, dependency_dir, {
                                    plugins: [
                                        decompressUnzip()
                                    ]
                                }).then(function (data) {
                                    if (data.length == 0) {
                                        logger.error("解压文件出错");
                                    } else {

                                        //根据不同的类型对商品进行处理
                                        if (type == config.workspace.goods_type.MK || type == "app_plugin") {
                                            logger.info("unzip_target");
                                            fs.readdir(dependency_dir, function (err, array) {
                                                if (err) {
                                                    return exe_callback(err, data, callback);
                                                }

                                                array.map(function (filename, i) {
                                                    //解压文件
                                                    decompress(path.join(dependency_dir, filename), dependency_dir, {
                                                        plugins: [
                                                            decompressUnzip()
                                                        ]
                                                    }).then(function (data) {
                                                        if (data.length == 0) {
                                                            exe_callback("解压文件出错", data, callback);
                                                            return false;
                                                        } else {
                                                            fs.unlink(path.join(dependency_dir, filename), function (err, data) {
                                                                if (err) {
                                                                    return exe_callback("删除临时文件出错", data, callback);
                                                                }
                                                                logger.info("解压完成");
                                                                logger.info("download success");
                                                                exe_callback(null, data, callback);
                                                                //epc.emit("download_success");
                                                            });

                                                        }
                                                    });
                                                });
                                            });
                                        } else {
                                            //解压文件

                                            logger.info("download success");
                                            exe_callback(null, data, callback);
                                        }

                                    }
                                });
                            })
                            fs.exists(dependency_dir, function (exists) {
                                if (!exists) {
                                    fs.mkdir(dependency_dir, function (err) {
                                        if (err) {
                                            return exe_callback(err, data, callback);
                                        }

                                        epc.emit("file_existed");

                                    });

                                } else {
                                    removeDir.remove(dependency_dir, function (err) {
                                        if (err) {
                                            return exe_callback(err, null, callback);
                                        }
                                        fs.mkdir(dependency_dir, function (err) {
                                            if (err) {
                                                return exe_callback(err, null, callback);
                                            }
                                            epc.emit("file_existed");

                                        });

                                    });
                                }

                            });



                            //临时数据 下载结束（无论成功失败）后删除
                            //LocalRepoProxy.addLocalRepo({
                            //    fileName: fileName,
                            //    version: version,
                            //    other_info: 'downloading'
                            //}, function (err, data) {
                            //    if (data && data.other_info == 'downloading') {
                            //        LocalRepoProxy.deleteFile(data._id, function (err, data) {
                            //            exe_callback(null, data, callback);
                            //        });
                            //    }
                            //    if (err) {
                            //        exe_callback("未知的错误，下载失败", data, callback);
                            //    }
                            //});
                        });
                    }
                }).on('error', function (err) {
                    exe_callback(err, null, callback);
                });
            } else {
                exe_callback("未知的错误，无法获取下载链接", null, callback);
            }
        } else {
            exe_callback(error, null, callback);
        }
    });
}


var CountDown = function (count, callback) {
    this.down = function () {
        if (!--count) callback(null, {
            successNum: successNum,
            errs: errs
        });
    }
    var successNum = 0;
    this.addSuccessNum = function () {
        successNum++;
    }
    var errs = [];
    this.addErrs = function (err) {
        errs.push(err);
    }
}

/**
 * 复制本地仓库文件到工作空间
 * @param：{tar_fullPath:"",fileNames:[]}
 * tar_fullPath 为全路径 fileNames数组中的文件名字一定要包含后缀名
 */
exports.copy = function (req, res, next) {
    var tar_fullPath = req.body.tar_fullPath;
    var fileNames = req.body["fileNames[]"];
    if (null != tar_fullPath && null != fileNames && fileNames.length > 0) {
        var countDown = new CountDown(fileNames.length, function (err, data) {
            res.json({
                data: data
            });
        });
        for (var i = 0; i < fileNames.length; i++) {
            copyFile({
                tar_fullPath: tar_fullPath,
                fileName: fileNames[i]
            }, function (err, data) {
                if (err) {
                    countDown.addErrs(err);
                } else {
                    countDown.addSuccessNum();
                }
                countDown.down();
            });
        }
    } else {
        res.json({
            data: false,
            err: "参数不全，无法拷贝"
        });
    }
}


/**
 * 复制本地仓库文件到工作空间
 * @param：{tar_fullPath:"",fileNames:[]}
 * tar_fullPath 为全路径 fileNames数组中的文件名字一定要包含后缀名
 */
exports.copyList = function (tar_fullPath, fileNames, call_back) {
    if (null != tar_fullPath && null != fileNames && fileNames.length > 0) {
        var countDown = new CountDown(fileNames.length, function (err, data) {
            exe_callback(err, data, call_back);
        });
        for (var i = 0; i < fileNames.length; i++) {
            copyFile({
                tar_fullPath: tar_fullPath,
                fileName: fileNames[i]
            }, function (err, data) {
                if (err) {
                    countDown.addErrs(err);
                } else {
                    countDown.addSuccessNum();
                }
                countDown.down();
            });
        }
    } else {
        exe_callback("参数不全，无法拷贝", null, call_back);
    }
}


/**
 *
 * 获取本地仓库
 */
exports.getLocalRepo = function (req, res, next) {
    LocalRepoProxy.getLocalRepo(function (err, data) {
        if (err) {
            return res.format_json(null, 500, err);
        }
        res.format_json(data, 0);
    });

}

exports.getFileInfoByName = function (req, res, next) {
    var fileName = req.params.file_name;
    LocalRepoProxy.getLocalRepoByFileName(fileName, function (err, data) {
        if (err) {
            return res.format_json(null, 500, err);
        }
        res.format_json(data, 0);
    })
}


/**
 *将本地仓库文件拷贝到其它位置
 */
function copyFile(param, callback) {
    if (null == param.fileName || param.fileName.trim().length == 0) {
        exe_callback("参数fileName为空，拷贝失败", null, callback);
    } else if (null == param.tar_fullPath || param.tar_fullPath.trim().length == 0) {
        exe_callback("参数tar_fullPath为空，拷贝失败", null, callback);
    } else {
        var fullFileName = path.join(local_repos, param.fileName);
        // var emitter = new events.EventEmitter();
        fs.exists(fullFileName, function (exists) {
            if (exists) {
                fs.lstat(param.tar_fullPath, function (err, stat) {
                    if (stat.isDirectory()) {
                        param.tar_fullPath = path.join(param.tar_fullPath, param.fileName);
                    }
                    var readStream = fs.createReadStream(fullFileName);
                    var writeStream = fs.createWriteStream(param.tar_fullPath);
                    writeStream.on('err', function (err, data) {
                        readStream.pause();
                        exe_callback(err, data, callback);
                    });
                    readStream.on('err', function (err, data) {
                        readStream.pause();
                        exe_callback(err, data, callback);
                    });
                    readStream.pipe(writeStream).on('finish', function () {
                        exe_callback(null, null, callback);
                    });
                });
            } else {
                exe_callback("文件" + fullFileName + "不存在,拷贝失败", null, callback);
            }
        });
    }
};

/**
 *删除本地仓库文件
 *param = {fileName:""}
 */
exports.deleteFile = function (param, callback) {
    if (null == param.fileName || param.fileName.trim().length == 0) {
        exe_callback(null, "参数fileName为空，无法执行删除", callback);
    } else {
        fs.exists(path.join(local_repos, param.fileName), function (exists) {
            if (exists) { //执行删除
                fs.unlink(path.join(local_repos, param.fileName), function (err, data) {
                    exe_callback(err, data, callback);
                })
            } else {
                exe_callback(null, "文件已经不存在，无需删除", callback);
            }
        });
    }
};


/**
 *执行callback
 */
function exe_callback(err, data, callback) {
    if (callback && typeof callback === 'function') {
        callback(err, data);
    }
}
exports.downloadGoods = downloadGoods;
exports.testLink = function (req, res, next) {

}